package com.gem.day04;

import java.util.Arrays;

/**
 * 本类用来演示Java数组的操作
 * 
 * @author easonsy
 * 2020年7月21日 下午1:32:49
 */
public class ArrayOperation {
	public static void main(String[] args) {
		int[] arr = { 2, 8, 4, 2, 1, 1, 8, 5 };
		//int[] arr = null;

		//排序功能
		//sortElement(arr);
		//System.out.println(Arrays.toString(arr));

		System.out.println(Arrays.toString(noRepeatElement(arr)));

		//int max = getMaxElement(arr);
		//System.out.println("最大值: " + max);

		//自定义数组元素添加功能
		/*int[] newArr = insertElement(arr, 5, 888);
		System.out.println(Arrays.toString(newArr));*/

		//System.out.println(Arrays.toString(deleteElementByIndex(arr, 1)));

		//System.out.println(Arrays.toString(deleteElementsByTarget(arr, 8)));

		/*
		 * 使用官方自带方法实现数组元素增删
		 * 
		 * 方法一:
		 * System.arraycopy(src, srcPos, dest, destPos, length);
		 * 
		 * src			原数组
		 * srcPos		从原数组第几个下标位置开始拷贝
		 * dest			目标数组
		 * destPos	拷贝到目标数组第几个下标位置去
		 * length		每次拷贝多少个元素
		 * 
		 * 方法二:
		 * Arrays.copyOf(arr,newLength)
		 * 一般在需要数组尾部定向扩容或者尾部删除时使用!
		 */
		//例如:删除原数组的4元素
		//1.创建一个长度-1的数组
		int[] deleteArr = new int[arr.length - 1];
		//2.调用数组拷贝方法
		System.arraycopy(arr, 0, deleteArr, 0, 2);
		System.arraycopy(arr, 3, deleteArr, 2, 5);
		System.out.println(Arrays.toString(deleteArr));

		//方式二:末尾增删
		int[] resultArr = Arrays.copyOf(arr, 5);
		System.out.println(Arrays.toString(resultArr));
	}

	/**
	 * 获取数组最大值
	 * 注意:如果方法参数类型是对象类型,一般需要做非空判断,从而避免空指针异常!
	 */
	public static int getMaxElement(int[] arr) {
		//非空判断
		if (arr == null) {
			//异常处理(后面课程再说)
			throw new RuntimeException("数组为空!");
		} else {
			//假设第一个元素是最大值
			int max = arr[0];
			//从第二个元素开始依次和这个最大值比较
			for (int i = 1; i < arr.length; i++) {
				//如果发现该值比max还大的话,则覆盖max的值
				if (arr[i] > max) {
					max = arr[i];
				}
			}
			return max;
		}
	}

	/**
	 *  在数组中添加元素
	 *  
	 *  注意:
	 *  Java数组一旦创建无法改变长度,如果要对数组进行增删元素操作,则需要
	 *  重新创建一个新数组,长度按照需求重新设置,然后把原数组中的元素拷贝
	 *  到新数组中
	 */
	public static int[] insertElement(int[] arr, int pos, int element) {
		//非空判断
		if (arr == null) {
			throw new RuntimeException("数组为空!");
		}
		//参数有效性判断
		if (pos < 0 || pos >= arr.length) {
			throw new RuntimeException("下标不合法!");
		}
		//创建新数组,长度是原数组长度+1
		int[] newArr = new int[arr.length + 1];
		//在pos位置添加新元素
		newArr[pos] = element;
		//分段赋值,pos
		//pos之前
		for (int i = 0; i < pos; i++) {
			newArr[i] = arr[i];
		}
		//pos之后
		for (int i = pos; i < arr.length; i++) {
			newArr[i + 1] = arr[i];
		}
		return newArr;
	}

	/**
	 * 根据下标删除数组元素
	 */
	public static int[] deleteElementByIndex(int[] arr, int index) {
		//非空判断
		if (arr == null) {
			throw new RuntimeException("数组为空!");
		}
		//参数有效性判断
		if (index < 0 || index >= arr.length) {
			throw new RuntimeException("下标不合法!");
		}
		int[] newArr = new int[arr.length - 1];
		int idx = 0;
		for (int i = 0; i < arr.length; i++) {
			if (i != index) {
				newArr[idx++] = arr[i];
			}
		}
		return newArr;
	}

	/**
	 * 根据元素删除元素
	 */
	public static int[] deleteElementsByTarget(int[] arr, int target) {
		//非空判断
		if (arr == null) {
			throw new RuntimeException("数组为空!");
		}
		//定义计数器,统计原数组中有多少个要被删除的元素
		int count = 0;
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] == target) {
				count++;
			}
		}
		//定义新数组,长度是原数组长度-count
		int[] newArr = new int[arr.length - count];
		//循环删除
		int idx = 0;
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] != target) {
				newArr[idx++] = arr[i];
			}
		}
		return newArr;
	}

	/**
	 * 数组元素排序
	 */
	public static void sortElement(int[] arr) {
		//非空判断
		if (arr == null) {
			throw new RuntimeException("数组为空!");
		}
		//使用JDK内置数组排序方法
		Arrays.sort(arr);

		/*
		 * 冒泡排序
		 * 依次两两相比较,交换两个数字,把大的往后排
		 */
		/*for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - 1 - i; j++) {
				if (arr[j + 1] < arr[j]) {
					//定义临时变量
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}*/

		/*
		 * 选择排序
		 * 首先在未排序序列中找到最小（大）元素，存放到排序序列的起始位置，
		 * 然后，再从剩余未排序元素中继续寻找最小（大）元素，然后放到已排序序列的末尾。
		 * 以此类推，直到所有元素均排序完毕。
		 */
		/*for (int i = 0; i < arr.length - 1; i++) {
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[i] > arr[j]) {
					int temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}*/
	}

	/**
	 * 数组元素排重
	 */
	public static int[] noRepeatElement(int[] arr) {
		//1.创建一个新数组,长度等于原数组
		int[] newArr = new int[arr.length];
		//2.把原数组中第一个元素拷贝到新数组中,然后直接按元素删除该元素
		int idx = 0;
		for (;;) {
			newArr[idx++] = arr[0];
			arr = deleteElementsByTarget(arr, arr[0]);
			if (arr.length == 0) {
				break;
			}
		}
		return Arrays.copyOf(newArr, idx);
	}
}
